package com.oxygen.pt.utils;

public final class Snowflake12 {
    // 2025-01-01 00:00:00 UTC
    private static final long EPOCH = 1735689600000L;
    private static final int MACHINE_BITS = 10;   // 最多 1024 台
    private static final int SEQ_BITS   = 12;     // 每毫秒 4096 序列
    private static final long MAX_MACHINE = ~(-1L << MACHINE_BITS);
    private static final long MAX_SEQ   = ~(-1L << SEQ_BITS);

    private final long machineId;
    private long lastTm = -1L;
    private long seq = 0L;

    public Snowflake12(long machineId) {
        if (machineId < 0 || machineId > MAX_MACHINE)
            throw new IllegalArgumentException("machineId 0-" + MAX_MACHINE);
        this.machineId = machineId;
    }

    public synchronized long next() {
        long tm = System.currentTimeMillis();
        if (tm < lastTm) throw new RuntimeException("时钟回退");
        if (tm == lastTm) {
            seq = (seq + 1) & MAX_SEQ;
            if (seq == 0) {               // 序列溢出，等下一毫秒
                while (tm <= lastTm) tm = System.currentTimeMillis();
            }
        } else seq = 0;
        lastTm = tm;

        long id = ((tm - EPOCH) << (MACHINE_BITS + SEQ_BITS))
                | (machineId << SEQ_BITS)
                | seq;

        // 63 位 → 12 位十进制：模 1 万亿
        return id % 1_000_000_000_000L;
    }
}